#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

typedef struct Thing
{
    int id;
    float    value;
    char     name[8];
} Thing;

Thing things[] =
{
    {3, 3.14, "pi"},
    {66, 6.666, "devil"},
    {100, 1.001, "hundred"},
    {7, 700, "dream"},
    {0x007, 0.07, "bond"}
};

int main()
{
    const char filename[] = "/tmp/binary.txt";
    FILE* file = fopen(filename, "w+"); // write and read (but file will be re-created

    if (!file)
    {
        fprintf(stderr, "failed to open file\n");
        exit(2);
    }

    int writeCount = sizeof(things) / sizeof(Thing);
    printf("writeCount: %d\n", writeCount);

    // write count of data to be written
    if( fwrite(&writeCount, sizeof(writeCount), 1, file) != 1)
    {
        fprintf(stderr, "incomplete write. error %d(%s)\n", errno, strerror(errno));
        return EXIT_FAILURE;
    }

    // write data
    int numWritten = fwrite(things, sizeof(Thing), writeCount, file);

    if (numWritten != writeCount)
    {
        fprintf(stderr, "incomplete write (%d of %d). error %d\n", numWritten, writeCount, errno);
        return EXIT_FAILURE;
    }

    // read
    fseek(file, 0, SEEK_SET);

    int readCount = 0;
    if (fread(&readCount, sizeof(readCount), 1, file) != 1)
    {
        fprintf(stderr, "failed to read number of data. error %d(%s)\n", errno, strerror(errno));
        return EXIT_FAILURE;
    }

    Thing* readThings = malloc(readCount);
    int numRead = fread(readThings, sizeof(Thing), readCount, file);
    if (numRead != readCount)
    {
        fprintf(stderr, "incomplete read (%d of %d). error %d\n", numRead, readCount, errno);
        return EXIT_FAILURE;
    }
    else
    {
        int i = 0;
        for (i = 0; i < readCount; ++i)
        {
            printf("> %d\t%g\t%s\n", readThings[i].id, readThings[i].value, readThings[i].name);
        }
    }

    free(readThings);
    fclose(file);

    return 0;
}
